require 'json'

class ScheduledRecord < ActiveRecord::Base
  belongs_to :wallet
  validates_presence_of :wallet

  has_and_belongs_to_many :operations, :autosave => true

  validates_presence_of :fromDate
  validates_presence_of :toDate
  validate :validateDates, :on => :create

  def validateDates
    if !fromDate.kind_of?(Integer)
      errors.add(:fromDate, "fromDate should be date in unix-time format")
      return
    end

    if !toDate.kind_of?(Integer)
      errors.add(:toDate, "toDate should be date in unix-time format")
      return
    end

    errors.add(:fromDate, "fromDate can't be more than toDate") if fromDate > toDate
    errors.add(:toDate, "toDate can't be less then current date") if toDate < Time.now.to_i
  end

  validates_presence_of :cron

  validates :tweetJson, :length => {
    :minimum   => 5,
    :maximum   => 1024,
    :too_short => "tweetJson is to short",
    :too_long  => "tweetJson is to long"
  }

  def tweetHash
    # TODO what if tweetJson be changed
    @tweetHash = JSON.parse(tweetJson) if @tweetHash.nil?
    @tweetHash
  end

  def generatedTo
    @generatedTo ||= fromDate;
  end

  def generatedFrom
    @generatedFrom ||= fromDate;
  end

  def occurrences fromDate, toDate
    date = fromDate
    dates = []
    while date < toDate
      dates << date
      date += 1.day
    end

    dates
  end

  #
  # The same interface like for Operation.from_options
  #
  # operation_params = {
  #   date: <unix time>
  #   comment: Text
  #   wallet: <Wallet Name>
  #   value: { # TODO here shouldn't be hash, should be plain params
  #     USD: 1000,
  #     BYR: 10000,
  #   }
  # }
  #
  def create_record user, options
    op = Operation.from_options(user, options)
    op.state = 0 # not-approved

    operations << op
    return op;
  end

  def create_record!
    return create_record nil, tweetHash
  end

  def generate!(toDate, user)
    return if generatedTo > toDate

    occurrences(generatedTo, toDate).each do |date|
      create_record(user, tweetHash.merge({date: date}))
    end

    generatedTo = toDate
    save!
  end

  def as_json(options = nil)
    {id: id, fromDate: fromDate, toDate: toDate, tweetJson: tweetJson, cron: cron, wallet: wallet.name}
  end
end
